package gestIT;

/**
 * Class that represent a generic gesture building block
 * 
 * @author nicola
 *
 */
public class TmpExp {

	/** Event Listener List that handle 'State Changed' Event	 */
	private EventListenerList OnStateChanged;
	/** Event Listener List that handle 'Completed' Event	 */
	public EventListenerList Completed;
	/** Event Listener List that handle 'Error' Event	 */
	public EventListenerList Error;
	/** Event Listener List that handle 'Performing' Event	 */
	public EventListenerList Performing;
	
	/** Current status of the building block */
	public ExecState state;
	/** Type of the building block */
	public ExpType type;
	/** Flag for iterative or non iterive building block */
	public boolean Iterative;
	/** Flag for optional or non optional building block */
	public boolean Optional;
	/** Reference to the parent building block */
	public TmpExp Parent;
	
	
	/**
	 * Constructor to create a new generic building block, no iterative and no optional; initally disabled.
	 */
	public TmpExp(){
        this.state = ExecState.Disabled;
        this.Parent = null;
        this.Iterative = false;
        this.Optional = false;
        this.type = ExpType.Simple;
        
        this.OnStateChanged = new EventListenerList();
        this.Completed = new EventListenerList();
        this.Error = new EventListenerList();
        this.Performing = new EventListenerList();
	}
	
	/**
	 * Method for changing the execution state of a building block
	 * @param st The new state for the building block
	 * @param tk The token that must be passed
	 */
	public void SetExecState(ExecState st, Token tk){
		this.state = st;
	}
	
	/**
	 * Getter for the actual building block state
	 * @return The actual state of the building block
	 */
	public ExecState getState(){
		return this.state;
	}
	
	
	/**
	 * Private method that invoke all the listeners registered to a specific StateChangedHandler
	 * @param obj A list of listeners returned from a EventListenerList.getListenerList()
	 * @param evt The event that has to be dispatched to all the listeners
	 * 
	 * Event Listener List is taken from javax.swing package
	 * For further information on Event Listener List:
	 * http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/event/EventListenerList.html
	 */
	private void RaiseListeners(Object[] obj, StateChangedEvent evt){
		for(int i = obj.length - 2; i >= 0; i -= 2){ 
            if(obj[i] == StateChangedHandler.class){ 
                ((StateChangedHandler)obj[i+1]).OnStateChanged(evt); 
            } 
        }
	}
	
	/**
	 * Dispatch an event of 'StateChanged' kind to all the listeners for that event 
	 * @param sender The sender of the event
	 * @param args The argument of the action that has generated the event
	 * @param tok The token that must be passed
	 */
	protected void RaiseOnStateChanged(TmpExp sender, ExpEventArgs args, Token tok){
		StateChangedEvent evt = new StateChangedEvent(sender, args, tok);
		RaiseListeners(OnStateChanged.getListenerList(), evt);
	}
	
	/**
	 * Dispatch an event of 'Completed' kind to all the listeners for that event 
	 * @param sender The sender of the event
	 * @param args The argument of the action that has generated the event
	 * @param tok The token that must be passed
	 */
	protected void RaiseCompleted(TmpExp sender, ExpEventArgs args, Token tok){
		StateChangedEvent evt = new StateChangedEvent(sender, args, tok);
		RaiseListeners(Completed.getListenerList(), evt);
	}
	
	/**
	 * Dispatch an event of 'Error' kind to all the listeners for that event 
	 * @param sender The sender of the event
	 * @param args The argument of the action that has generated the event
	 * @param tok The token that must be passed
	 */
	protected void RaiseError(TmpExp sender, ExpEventArgs args, Token tok){
		StateChangedEvent evt = new StateChangedEvent(sender, args, tok);
		RaiseListeners(Error.getListenerList(), evt);
	}
	
	/**
	 * Dispatch an event of 'Performing' kind to all the listeners for that event 
	 * @param sender The sender of the event
	 * @param args The argument of the action that has generated the event
	 * @param tok The token that must be passed
	 */
	protected void RaisePerforming(TmpExp sender, ExpEventArgs args, Token tok){
		StateChangedEvent evt = new StateChangedEvent(sender, args, tok);
		RaiseListeners(Performing.getListenerList(), evt);
	}
	
	/**
	 * Add a new listener for 'StateChanged' events
	 * @param lst The listener that will be added to the list of listeners
	 */
	public void addOnStateChangedListener(StateChangedHandler lst){
		OnStateChanged.add(StateChangedHandler.class, lst);
	}
	
	/**
	 * Remove a listener for 'StateChanged' events
	 * @param lst The listener that will be removed to the list of listeners
	 */
	public void removeOnStateChangedListener(StateChangedHandler lst){
		OnStateChanged.remove(StateChangedHandler.class, lst);
	}
	
	/**
	 * Add a new listener for 'Completed' events
	 * @param lst The listener that will be added to the list of listeners
	 */
	public void addCompletedListener(StateChangedHandler lst){
		Completed.add(StateChangedHandler.class, lst);
	}
	/**
	 * Remove a listener for 'Completed' events
	 * @param lst The listener that will be removed to the list of listeners
	 */
	public void removeCompletedListener(StateChangedHandler lst){
		Completed.remove(StateChangedHandler.class, lst);
	}
	
	/**
	 * Add a new listener for 'Error' events
	 * @param lst The listener that will be added to the list of listeners
	 */
	public void addErrorListener(StateChangedHandler lst){
		Error.add(StateChangedHandler.class, lst);
	}
	/**
	 * Remove a listener for 'Error' events
	 * @param lst The listener that will be removed to the list of listeners
	 */
	public void removeErrorListener(StateChangedHandler lst){
		Error.remove(StateChangedHandler.class, lst);
	}
	
	/**
	 * Add a new listener for 'Performing' events
	 * @param lst The listener that will be added to the list of listeners
	 */
	public void addPerformingListener(StateChangedHandler lst){
		Performing.add(StateChangedHandler.class, lst);
	}
	/**
	 * Remove a listener for 'Performing' events
	 * @param lst The listener that will be removed to the list of listeners
	 */
	public void removePerformingListener(StateChangedHandler lst){
		Performing.remove(StateChangedHandler.class, lst);
	}
	
}
